package com.atguigu.tingshu.common.thread;

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author: atguigu
 * @create: 2024-04-09 14:23
 */
@Slf4j
@Configuration
public class ThreadPoolConfig {

    /**
     * 线程池：核心线程数=最大线程数
     * 应用类型：
     * CPU密集型：N+1
     * I O密集型：2N+1
     *
     * @return
     */
    @Bean
    public ThreadPoolExecutor threadPoolExecutor() {
        //获取CPU核心数
        int count = Runtime.getRuntime().availableProcessors();
        int threadCount = count * 2;
        //1.创建线程池对象
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                threadCount, //核心线程数
                threadCount, //最大线程数
                0,           //非核心线程空闲时间
                TimeUnit.SECONDS, //时间单位
                new ArrayBlockingQueue<>(200), //阻塞队列
                Executors.defaultThreadFactory(), //线程工厂对象用于产生线程
                (runnable, executor) -> {     //拒绝策略 1.默认抛出异常，任务丢弃 2.静默方式丢弃新任务 3.静默方式丢弃阻塞队队首任务  4.调用者线程执行（确保任务不丢失）
                    log.error("[ThreadPool]触发线程池拒绝策略,再次尝试给线程池执行");
                    try {
                        Thread.sleep(200);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                    executor.submit(runnable);
                }
        );
        //2.创建线程池同时启动核心线程
        threadPoolExecutor.prestartCoreThread();
        return threadPoolExecutor;
    }
}
